import { Cell, Graph, Node } from "@antv/x6";
import { Dnd } from "@antv/x6-plugin-dnd";
import { Selection } from "@antv/x6-plugin-selection";
import { Snapline } from "@antv/x6-plugin-snapline";
import { Transform } from "@antv/x6-plugin-transform";
import BizNode from "./BizNode";
import { Keyboard } from "@antv/x6-plugin-keyboard";

export declare interface Board {
    // 图图
    graph: Graph

    // 是否正可以交互
    interacting: boolean
    getGraph(): Graph | undefined
    setGraph(graph: Graph)
    getNode(id: string): Cell | undefined
    isInteracting(): boolean
    setInteracting(interacting: boolean)
}

export declare interface EditorBoard extends Board {
    dnd: Dnd
    addRandomNode(x: number, y: number)
    createBizNode(item: any): Node
}

export class Editor implements EditorBoard {
    dnd: Dnd;
    graph: Graph
    interacting: boolean = true
    addRandomNode(x: number, y: number) {
        let keys = Object.keys(BizNode)
        let index = Math.floor(Math.random() * keys.length)
        let node = BizNode[keys[index]]
        node.x = x
        node.y = y
        this.graph.addNode(node)
    }
    createBizNode(item: any): Node {
        return this.graph.createNode(item)
    }
    setGraph(graph: Graph) {
        this.graph = graph
    }

    getGraph(): Graph | undefined {
        return this.graph
    }
    isInteracting(): boolean {
        return this.interacting
    }
    setInteracting(interacting: boolean) {
        this.interacting = interacting
    }

    getNode(id: string): Cell | undefined {
        return this.graph.getCellById(id)
    }

    loadPlugins() {
        const graph = this.graph
        graph.use(
            new Snapline({
                enabled: true,
            }),
        )
        graph.use(
            new Transform({
                resizing: { enabled: true },
                rotating: { enabled: true },
            }),
        )
        graph.use(
            new Selection({
                enabled: true,
            }),
        )
        this.graph.use(
            new Keyboard({
                enabled: true,
                global: true,
            }),
        )
        this.dnd = new Dnd({
            target: graph,
        })
    }
}

export class Previewer implements Board {
    graph: Graph
    interacting: boolean = false

    // constructor(graph: Graph) {
    //     this.graph = graph
    // }
    setGraph(graph: Graph) {
        this.graph = graph
    }

    getGraph(): Graph | undefined {
        return this.graph
    }

    isInteracting(): boolean {
        return this.interacting
    }
    setInteracting(interacting: boolean) {
        this.interacting = interacting
    }

    getNode(id: string): Cell | undefined {
        return this.graph.getCellById(id)
    }

    addRandomNode(x: number, y: number) {
        let node: Cell = this.graph.addNode({
            shape: 'rect',
            width: 100,
            height: 40,
            x: x,
            y: y,
            label: 'Hello',
            attrs: {
                body: {
                    stroke: '#8f8f8f',
                    strokeWidth: 1,
                    fill: '#fff',
                    rx: 6,
                    ry: 6,
                }
            }
        })
        return node
    }

    /**
     * 测试功能
     * 1. 双击添加节点
     * 2. 第一个节点作为父节点，连接后续添加的所有节点
     * 3. 连线添加节点工具，点击空白消除，双击连线重新添加节点工具
     * 4. 节点工具无法通过interacting控制
     */
    bindBlankEvent() {

        let mainNode: Cell
        let graph = this.graph
        function lineTo(subNode: Cell): void {
            console.log(mainNode, "lineTo", subNode);

            if (!mainNode) {
                mainNode = subNode
                return
            }
            graph.addEdge({
                source: mainNode,
                target: subNode,
                tools: [
                    {
                        name: 'vertices',
                        args: {
                            attrs: { fill: '#666' },
                        },
                    },
                    {
                        name: 'segments',
                        args: {
                            snapRadius: 20,
                            attrs: {
                                fill: '#444',
                            },
                        },
                    }
                ]
            })
        }
        let listener = this.graph.on('blank:dblclick', ({ e, x, y }) => {
            let node: Cell = this.addRandomNode(x, y)
            lineTo(node)
        })
        this.graph.on('blank:click', ({ e, x, y }) => {
            graph.getCells().forEach(cell => {
                if (cell.shape == "edge") {
                    cell.removeTools()
                }
            })


        })
        this.graph.on('edge:dblclick', ({ e, edge, view }) => {
            console.log("edge db", edge);

            edge.addTools([{
                name: 'vertices',
                args: {
                    attrs: { fill: '#777' },
                },
            },
            {
                name: 'segments',
                args: {
                    snapRadius: 20,
                    attrs: {
                        fill: '#444',
                    },
                },
            }])
        })

    }
}

export const boardBuilder = {
    createDefaultBoard(dom: HTMLElement): Previewer {
        const board = new Previewer()
        let graph: Graph = new Graph({
            container: dom,
            autoResize: true,
            background: {
                color: '#F2F7FA',
            },
            grid: {
                size: 10, // 网格大小 10px
                visible: true, // 绘制网格，默认绘制 dot 类型网格
            },
            interacting: function () {
                return board.isInteracting()
            }
        })
        board.setGraph(graph)
        return board
    },
    createDefaultEditor(dom: HTMLElement): Editor {
        const board = new Editor()
        let graph: Graph = new Graph({
            container: dom,
            autoResize: true,
            background: {
                color: '#F2F7FA',
            },
            grid: {
                size: 10, // 网格大小 10px
                visible: true, // 绘制网格，默认绘制 dot 类型网格
            },
            interacting: function () {
                return board.isInteracting()
            }
        })
        board.setGraph(graph)
        // 加载插件
        board.loadPlugins()
        return board
    }
}